package drds.global_transaction.api.message_codec;

import drds.common.Constants;
import drds.common.Log;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class ResponseMessages extends Message implements IMessages
{
	private static final long serialVersionUID = -7719219648774528552L;
	@Setter
	@Getter
	public ResponseMessage[] responseMessages;

	@Override
	public boolean decode(ByteBuf byteBuf)
	{
		int readableBytes = byteBuf.readableBytes();
		if (readableBytes < 4)
		{
			return false;
		}

		readableBytes -= 4;
		int length = byteBuf.readInt();
		if (readableBytes < length)
		{
			return false;
		}
		// from byteBuf to byteBuffer
		byte[] bytes = new byte[length];
		byteBuf.readBytes(bytes);
		ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
		decode(byteBuffer);
		return true;
	}

	public void decode(ByteBuffer byteBuffer)
	{
		short messageNum = byteBuffer.getShort();
		responseMessages = new ResponseMessage[messageNum];
		for (int index = 0; index < messageNum; index++)
		{
			short typeCode = byteBuffer.getShort();
			ResponseMessage responseMessage = (ResponseMessage) MessageCodecs.getMessageCodec(typeCode);
			responseMessage.decode(byteBuffer);// 依次进行解码
			responseMessages[index] = responseMessage;
		}
	}

	@Override
	public byte[] encode()
	{
		ByteBuffer byteBuffer = ByteBuffer.allocate(responseMessages.length * 1024);
		byteBuffer.putShort((short) responseMessages.length);

		Map<Message, Integer> messageToBytesMap = new HashMap<Message, Integer>();
		for (Message message : responseMessages)
		{
			byte[] bytes = message.encode();
			byteBuffer.putShort(message.getTypeCode());
			byteBuffer.put(bytes);
			//
			messageToBytesMap.put(message, bytes.length);
			//
		}
		//
		byteBuffer.flip();
		int length = byteBuffer.limit();
		byte[] bytes = new byte[length + 4];
		//
		intToBytes(length, bytes, 0);
		//
		byteBuffer.get(bytes, 4, length);

		//
		if (Constants.developMode)
		{
			for (Map.Entry<Message, Integer> entry : messageToBytesMap.entrySet())
			{
				Log.debugWithLine(log, Thread.currentThread(), "待发送的消息类型是:" + entry.getKey().getClass().getSimpleName() + ",消息的大小是:" + entry.getValue());
			}
		}
		return bytes;
	}

	@Override
	public short getTypeCode()
	{
		return type_response_messages;
	}

}
